<html>
<head>
  <title>0. 图例含义及代码实现</title>
  <basefont face="微软雅黑" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="YXBJ Windows/602628 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
  <style>
    body, td {
      font-family: 微软雅黑;
      font-size: 10pt;
    }
  </style>
</head>
<body>
<a name="19069"/>
<h1>0. 图例含义及代码实现</h1>
<div>
<table bgcolor="#D4DDE5" border="0">
<tr><td><b>创建时间：</b></td><td><i>2020/3/11 17:30</i></td></tr>
<tr><td><b>更新时间：</b></td><td><i>2020/5/18 6:12</i></td></tr>
<tr><td><b>作者：</b></td><td><i>Long Life Student</i></td></tr>
</table>
</div>
<br/>

<div>
<span><div><div>在深入学习设计模式之前，需要仔细研究一下在设计模式书中出现的各种图例，从代码实现的层次上研究一下。</div><div>比如都知道所谓的类图之间的关系有关联、依赖、组合、聚合等，但是这些名词其实并不理解，只有从代码实现上理解了这些关系，才能真正看懂类图。</div><div><br/></div><div>《设计模式：可复用面向对象软件的基础》这本书中的各种图例使用的是OMT表示法，其他的书籍，如《大话设计模式》、《设计模式之禅》使用的是UML，这两种表示方法不太相同，主要区别在类图上，这也是我应该着重研究的。</div><div><br/></div><div>一、OMT表示法的图例</div><div>在《设计模式：可复用面向对象软件的基础》这本书中，总共有三类图例，类图、对象图、交互图。</div><div><span style="font-weight: bold;">1.交互图</span></div><div><img src="0. 图例含义及代码实现_files/Image.png" type="image/png" data-filename="Image.png" width="1094"/></div><div>这里的交互图其实就是UML中的时序图，这个图能够看懂，没什么说的。</div><div><span style="font-weight: bold;">2.类图</span></div><div>类图有些复杂了：</div><div><span style="font-weight: bold;">（1）抽象类与具体类</span></div><div>斜体表示类或者方法是抽象的。</div><div><img src="0. 图例含义及代码实现_files/Image [1].png" type="image/png" data-filename="Image.png" width="1241"/></div><div><span style="font-weight: bold;">（2）参与客户类与绝对客户类</span></div><div><img src="0. 图例含义及代码实现_files/Image [2].png" type="image/png" data-filename="Image.png" width="801"/></div><div>参与客户类：客户是设计模式的参与者（即该客户类在这个模式中承担一定的责任）。</div><div>绝对客户类：客户不是设计模式的参与者（即客户类在模式中不承担责任）。</div><div><span style="font-weight: bold;">（3）类关系</span></div><div>这是类图的重点，类的关系有：类继承、部分或聚集关系的对象引用、相识关系、创建关系、多余一个的聚集关系等。</div><div><img src="0. 图例含义及代码实现_files/Image [3].png" type="image/png" data-filename="Image.png" width="1425"/></div><div>这里的重点就是把类的关系搞懂。</div><div><span style="font-weight: bold;">a)实例化</span></div><div><img src="0. 图例含义及代码实现_files/Image [4].png" type="image/png" data-filename="Image.png" width="844"/></div><div>虚箭头线表示一个类实例化另一个类的对象，箭头指向被实例化的对象的类。</div><div>Instantiator类实例化Instantiatee类的对象，Instantiator类不拥有Instantiatee类的对象，只是创建一下。（考虑工厂模式）</div><div><span style="font-weight: bold;">b)继承</span></div><div><img src="0. 图例含义及代码实现_files/Image [5].png" type="image/png" data-filename="Image.png" width="322"/></div><div>类subclass继承于parentclass，箭头指向的类是父类。</div><div><span style="font-weight: bold;">c)相识</span></div><div><img src="0. 图例含义及代码实现_files/Image [6].png" type="image/png" data-filename="Image.png" width="1223"/></div><div>箭头线表示一个类对另一个类实例的引用关系。</div><div>个人理解，通过指针或者引用实现，Window类中，通过指针或者引用使用了Rectangle类的对象。（但应该不是通过成员函数使用的）</div><div><span style="font-weight: bold;">d)聚合</span></div><div><img src="0. 图例含义及代码实现_files/Image [7].png" type="image/png" data-filename="Image.png" width="993"/></div><div>聚合是定义真正实例的成员变量，或者将这些成员变量定义为实例指针或引用。</div><div>Aggregator类中，定义了Agregatee类的对象。</div><div><span style="font-style: italic;">注意，不一定是成员变量，可能是成员函数中使用到了另一个类的对象。</span></div><div><span style="font-weight: bold;">注意：</span>聚合与相识容易混淆，个人认为，聚合的表现是成员变量，相识的表现只是在一个类中使用到了另外的一个类，如何使用可能是成员函数的一个参数（对不对？）</div><div>又或者是聚合表示一个成员对象，委托表示成员引用或指针（64页）？</div><div><span style="font-weight: bold;">e)多于一个</span></div><div><img src="0. 图例含义及代码实现_files/Image [8].png" type="image/png" data-filename="Image.png" width="1425"/></div><div>图中，Drawing和Shape之间的关系中，有一个实心圆点，表示“多于一个”，说明Drawing类中聚合了多于一个的Shape，即，Drawing类中定义了多个Shape类的对象作为成员变量，成员变量的名称是shapes。</div><div><span style="font-weight: bold;">（4）伪代码注解</span></div><div>简要说明方法的实现。</div><div><img src="0. 图例含义及代码实现_files/Image [9].png" type="image/png" data-filename="Image.png" width="876"/></div><div><span style="font-weight: bold;">3.对象图</span></div><div><img src="0. 图例含义及代码实现_files/Image [10].png" type="image/png" data-filename="Image.png" width="812"/></div><div>书上的说法：对象图仅仅描述实例。它描述了设计模式中的对象某个时刻的状况。对象的名字通常表示为aSomething，其中，Something是该对象的类。表示对象的符号是一个圆角矩形，并以一条直线将对象名与对象引用分开。箭头表示对象引用。</div><div>个人理解：也就是说，上图的三个圆角矩形表示某一个时刻的类的对象，途中的意思是，有一个Drawing类的对象，对象中，有两个成员shape[0]和shape[1]，每一个成员指向另一个对象，shape[0]是CircleShape类的一个对象的引用，shape[1]是LineShape对象的引用。</div><div><br/></div><div>二、UML表示法的图例</div><div>对于UML，我不太明白的只有类图中的各种关系如何具体实现，所以这里仅对类图进行讨论。</div><div>以下描述摘自《大话设计模式》一书。</div><div>一个典型的类图：</div><div><img src="0. 图例含义及代码实现_files/Image [11].png" type="image/png" data-filename="Image.png" width="1179"/></div><div>其中，有以下几个类图元素：</div><div><span style="font-weight: bold;">1）类图</span></div><div><img src="0. 图例含义及代码实现_files/Image [12].png" type="image/png" data-filename="Image.png" width="530"/></div><div>类图分为三层：</div><ul><li><div>类名，如果是抽象类，则用斜体表示。</div></li><li><div>成员变量，</div></li><li><div>成员函数，'+'表示public，'-'表示private，'#'表示protected</div></li></ul><div><span style="font-weight: bold;">2）接口</span></div><div><img src="0. 图例含义及代码实现_files/Image [13].png" type="image/png" data-filename="Image.png" width="1453"/></div><div>接口有两种表示方法。</div><div>另外，Java中有明确的接口，C++中接口的表示是不是虚基类？估计在C++中很难区分接口和父类。（没有明确的语法设施）</div><div><span style="font-weight: bold;">3）继承</span></div><div><img src="0. 图例含义及代码实现_files/Image [14].png" type="image/png" data-filename="Image.png" width="501"/></div><div>继承关系用空心三角形+实线来表示。   </div><div>鸟继承于动物，动物是一个抽象类，鸟是动物的子类。</div><div><img src="0. 图例含义及代码实现_files/Image [15].png" type="image/png" data-filename="Image.png" width="690"/></div><div><span style="font-weight: bold;">4）接口实现</span></div><div><img src="0. 图例含义及代码实现_files/Image [16].png" type="image/png" data-filename="Image.png" width="386"/></div><div>接口实现使用空心三角形+虚线表示。</div><div>大雁实现飞翔的接口。</div><div><img src="0. 图例含义及代码实现_files/Image [17].png" type="image/png" data-filename="Image.png" width="676"/></div><div><span style="font-weight: bold;">5）关联关系（association）</span></div><div><img src="0. 图例含义及代码实现_files/Image [18].png" type="image/png" data-filename="Image.png" width="444"/></div><div>关联关系表示一个类知道另一个类，实际上就是箭头指向的类的对象是箭头发源的类的一个成员变量。气候是企鹅的成员变量。</div><div>线段两端可能有基数（见合成关系描述）。</div><div><img src="0. 图例含义及代码实现_files/Image [19].png" type="image/png" data-filename="Image.png" width="1423"/></div><div><span style="font-weight: bold;">6）聚合关系（Aggregation）</span></div><div><img src="0. 图例含义及代码实现_files/Image [20].png" type="image/png" data-filename="Image.png" width="419"/></div><div>聚合表示一种弱的拥有关系，体现的是A对象可以包含B对象，但B对象不是A对象的一部分。</div><div>在上图的例子中，大雁是群居动物，每只大雁都属于一个雁群，一个雁群可以有多只大雁。</div><div>线段两端可能有基数（见合成关系描述）。</div><div><img src="0. 图例含义及代码实现_files/Image [21].png" type="image/png" data-filename="Image.png" width="1413"/></div><div><span style="font-weight: bold;">7）合成（组合）关系（Composition）</span></div><div><img src="0. 图例含义及代码实现_files/Image [22].png" type="image/png" data-filename="Image.png" width="726"/></div><div>合成是一种强的拥有关系，体现了严格的部分和整体的关系，部分和整体的生命周期一样。</div><div>合成关系的连线两端还有一个数字，这被称为基数，表明这一端的类可以有几个实例。如果一个类可能有无数个实例，则用n来表示。</div><div>上图示例中，鸟和翅膀就是合成关系，因为它们是部分和整体的关系，并且翅膀和鸟的声明周期是相同的！</div><div><img src="0. 图例含义及代码实现_files/Image [23].png" type="image/png" data-filename="Image.png" width="1451"/></div><div>注意：关联、聚合、组合这三种关系之间的区别不容易区分。个人理解：</div><ul><li><div>关联关系是一个类的对象是另一个类的成员变量，二者生命周期不做要求（这一点是与组合关系的区别）；</div></li><li><div>聚合关系是一个类的对象是另一个类的成员变量数组，二者生命周期不做要求；</div></li><li><div>组合关系是一个类的对象是另一个类的成员变量，二者生命周期必须一致。</div></li></ul><div>8）依赖关系</div><div><img src="0. 图例含义及代码实现_files/Image [24].png" type="image/png" data-filename="Image.png" width="877"/></div><div>依赖关系一般体现为只是在类中的成员函数中使用到，并不是类的一个成员变量。</div><div><img src="0. 图例含义及代码实现_files/Image [25].png" type="image/png" data-filename="Image.png" width="1419"/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div><div><br/></div></div><div><br/></div></span>
</div></body></html> 